#pragma once

#include "corebase_global.h"
#include <osg\ref_ptr>
#include "templateclass.h"
#include <osg/Referenced>
#include "odeworldwrap.h"
#include <osg/Vec3>
#include <ode/common.h>
#include <ode/collision_space.h>

namespace CoreBase
{
	class Transformable;
	class ODEWorldWrap;

	class COREBASE_EXPORT ODESpaceWrap : public osg::Referenced
	{
	public:
		ODESpaceWrap(ODEWorldWrap* worldWrapper);
		void registerCollidable(Transformable* collidable);
		void unRegisterCollidable(Transformable* collidable);
		void collide();
		void postCollide();
		void setUserCollisionCallback(dNearCallback* func, void* data=NULL);
		dNearCallback* getUserCollisionCallback() const;
		void* getUserCollisionData();
		const void* getUserCollisionData() const;
		struct COREBASE_EXPORT CollisionData
		{
			Transformable* _bodies[2];
			osg::Vec3 _location;
			osg::Vec3 _normal;
			float _depth;
		};
		template<typename T>
		void setDefaultCollisionCBFunc(void (T::*function)(CollisionData),T* obj)
		{
			_callbackFunc = new Type_1Func<void,T,CollisionData>(function,obj);
		}
		dJointGroupID getContactJoinGroupID() const;
		dSpaceID getSpaceID() const;
	protected:
		virtual ~ODESpaceWrap();
	private:
		static void defaultNearCallback(void* data, dGeomID o1, dGeomID o2);
		dSpaceID								_spaceID;
		dNearCallback*							_userNearCallback;
		void*									_userNearCallbackData;
		dJointGroupID							_contactJointGroupID;
		osg::ref_ptr<ODEWorldWrap>				_worldWrapper;
		osg::ref_ptr<FuncBase>					_callbackFunc;
	};
}